var $ = exports

var log = java.util.logging.Logger.getLogger("tengo")

var objectUtils = require("objectUtils")
var arrayUtils = require("arrayUtils")

var ds = com.google.appengine.api.datastore

var datastore = ds.DatastoreServiceFactory.datastoreService

var jsToEntity = function(obj) {
	
	var entity = obj.key ? new ds.Entity(obj.key) : new ds.Entity(obj.kind)
	for (var i in obj) {
		if (i !== "key") {
			var value = obj[i]
			entity.setProperty(
				i, 
				typeof value === "number" ? new java.lang.Double(value) : value
			) 
		}
	}
	return entity
}

var entityToJs = function(entity) {
	var obj = {}
	var it = entity.properties.entrySet().iterator()
	while( it.hasNext() ) {
		var entry = it.next()
		obj[entry.key] = entry.value
	}
	obj.key = entity.key
	return obj
}

var keyArray = function(keys) {
	return keys.flatten().toJavaArray(ds.Key)
}

$.get = function(key) {	return entityToJs(datastore.get(key)) }
$.put = function(obj) {	return datastore.put(jsToEntity(obj)) }
$.runQuery = function(query) { 
	return arrayUtils.fromIterator(datastore.prepare(query).asIterator()) 
}
$.remove = function() { 
	datastore["delete"](keyArray(arrayUtils.fromArguments(arguments))) 
}

var transactionWrapperProto = {
	commit: function() { this.gTransaction.commit() },
	put: function(obj) { 
		return datastore.put(this.gTransaction, jsToEntity(obj)) 
	},
	get: function(key) { 
		return entityToJs(datastore.get(this.gTransaction, key))
	},
	isActive: function() { return this.gTransaction.active }
}

var transactionWrapper = function() {
	
	var tr = objectUtils.beget(transactionWrapperProto)
	tr.gTransaction = datastore.beginTransaction()
	return tr
}

$.transaction = function(f) {
	var transaction = transactionWrapper()
	f(transaction)
	if (transaction.isActive()) {
		transaction.commit()
	}
}

$.query = function(params) {
	params = params || {}
	if (params.kind) {
		return new ds.Query["(java.lang.String)"](params.kind)
	} else {
		return new ds.Query["()"]()
	}
}